package cn.com.shopec.erp.system.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.hibernate.Hibernate;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.shopec.erp.common.page.PageFinder;
import cn.com.shopec.erp.common.page.PageQuery;
import cn.com.shopec.erp.common.utils.MD5Util;
import cn.com.shopec.erp.common.utils.StringUtil;
import cn.com.shopec.erp.system.common.UserUtils;
import cn.com.shopec.erp.system.constant.SystemConstant;
import cn.com.shopec.erp.system.dao.IUserDao;
import cn.com.shopec.erp.system.entity.Role;
import cn.com.shopec.erp.system.entity.User;
import cn.com.shopec.erp.system.service.IRoleService;
import cn.com.shopec.erp.system.service.IUserService;
import cn.com.shopec.erp.system.vo.RoleVo;
import cn.com.shopec.erp.system.vo.UserVo;

/**
 * 
 * @ClassName UserServiceImpl
 * @Description 用户Service实现
 * @author chengui
 * @date 2013-5-30 上午11:01:44
 */
@Service
public class UserServiceImpl implements IUserService {
	
	@Resource private IRoleService roleService;
	
	@Resource private IUserDao userDao;

	@Override
	public PageFinder<UserVo> getPagedUserVos(UserVo userVo, PageQuery pageQuery)
			throws Exception {
		PageFinder<User> pagedUsers = getPagedUsers(userVo, pageQuery);
		PageFinder<UserVo> pagedUserVos = new PageFinder<UserVo>(pagedUsers.getPageNo(), pagedUsers.getPageSize(), pagedUsers.getRowCount());
		List<UserVo> userVos = convertToUserVos(pagedUsers.getData());
		pagedUserVos.setData(userVos);
		return pagedUserVos;
	}
	
	/**
	 * 
	 * @MethodName convertToUserVos
	 * @Description 将用户集合转换成用户Vo集合
	 * @author chengui
	 * @date 2013-5-30 下午1:38:24
	 * @param data
	 * @return List<UserVo>
	 */
	private List<UserVo> convertToUserVos(List<User> data) {
		List<UserVo> userVos = new ArrayList<UserVo>();
		if (null != data && data.size() > 0) {
			UserVo userVo = null;
			for (User user : data) {
				userVo = new UserVo();
				convertToUserVo(user, userVo);
				userVos.add(userVo);
			}
		}
		return userVos;
	}
	
	/**
	 * 
	 * @MethodName convertToUserVo
	 * @Description 将用户转换成用户Vo
	 * @author chengui
	 * @date 2013-5-30 下午1:39:29
	 * @param user
	 * @param userVo
	 */
	private void convertToUserVo(User user, UserVo userVo) {
		BeanUtils.copyProperties(user, userVo);
	}

	/**
	 * 
	 * @MethodName getPagedUsers
	 * @Description 分页查询供应链用户
	 * @author chengui
	 * @date 2013-5-30 下午1:33:12
	 * @param userVo
	 * @param pageQuery
	 * @return PageFinder<User>
	 */
	private PageFinder<User> getPagedUsers(UserVo userVo, PageQuery pageQuery) {
		DetachedCriteria criteria = userDao.createCriteria();
		if (null != userVo) {
			if (StringUtil.isExist(userVo.getRealName())) {
				criteria.add(Restrictions.like("realName", userVo.getRealName(), MatchMode.ANYWHERE));
			}
			if (StringUtil.isExist(userVo.getUserName())) {
				criteria.add(Restrictions.like("userName", userVo.getUserName(), MatchMode.ANYWHERE));
			}
		}
		UserVo uv = UserUtils.getUserVo();
		if (null != uv && uv.getUserNature() != SystemConstant.USER_NATURE_2) {
			criteria.add(Restrictions.eq("userName", uv.getUserName()));
		}
		criteria.add(Restrictions.eq("deleteFlag", SystemConstant.DELETE_FLAG_1));
		PageFinder<User> pagedUsers = userDao.pagedByCriteria(criteria, pageQuery.getPage(), pageQuery.getPageSize());
		return pagedUsers;
	}

	@Override
	public void addUser(UserVo userVo) throws Exception {
		User user = new User();
		user.setRealName(userVo.getRealName());
		user.setUserName(userVo.getUserName());
		user.setPwd(MD5Util.MD5Encode(userVo.getPwd(), SystemConstant.CHARSET_UTF8));
		userDao.save(user);
	}

	@Override
	public String isUserExist(UserVo userVo) throws Exception {
		User user = null;
		if (null != userVo) {
			if (StringUtil.isExist(userVo.getUserName())) {
				user = userDao.findUniqueBy("userName", userVo.getUserName());
			}
		}
		if (null != user) {
			return SystemConstant.USER_EXISTS_YES;
		} else {
			return SystemConstant.USER_EXISTS_NO;
		}
	}

	@Override
	public UserVo getUserVo(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		UserVo uv = new UserVo();
		convertToUserVo(user, uv);
		return uv;
	}
	
	@Transactional
	@Override
	public void modifyUser(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		user.setRealName(userVo.getRealName());
		user.setUserName(userVo.getUserName());
		user.setLoginCount(userVo.getLoginCount());
		user.setUserStatus(userVo.getUserStatus());
		user.setEnableTime(userVo.getEnableTime());
		userDao.update(user);
	}
	
	@Transactional
	@Override
	public String modifyPassword(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		if (user.getPwd().equals(MD5Util.MD5Encode(userVo.getOldPwd(), SystemConstant.CHARSET_UTF8))) {
			user.setPwd(MD5Util.MD5Encode(userVo.getPwd(), SystemConstant.CHARSET_UTF8));
			userDao.update(user);
			return SystemConstant.SUCCESS;
		} else {
			return SystemConstant.PASSWORD_NOT_CORRECT;
		}
	}
	
	@Transactional
	@Override
	public void lockUser(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		user.setUserStatus(SystemConstant.USER_STATUS_2);
		userDao.update(user);
	}
	
	@Transactional
	@Override
	public void unlockUser(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		user.setUserStatus(SystemConstant.USER_STATUS_1);
		userDao.update(user);
	}

	@Override
	public void deleteUser(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		user.setDeleteFlag(SystemConstant.DELETE_FLAG_0);
		userDao.update(user);
	}

	@Override
	public List<RoleVo> getOwnRoleVos(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		Hibernate.initialize(user.getRoles());
		Set<Role> roles = user.getRoles();
		List<RoleVo> roleVos = convertToRoleVos(roles);
		return roleVos;
	}
	
	/**
	 * 
	 * @MethodName convertToRoleVos
	 * @Description 将角色集合转换成角色Vo集合
	 * @author chengui
	 * @date 2013-5-30 下午8:32:23
	 * @param roles
	 * @return
	 */
	private List<RoleVo> convertToRoleVos(Set<Role> roles) {
		List<RoleVo> roleVos = new ArrayList<RoleVo>();
		if (null != roles && roles.size() > 0) {
			RoleVo roleVo = null;
			for (Role role : roles) {
				if (role.getDeleteFlag() != 0) {
					roleVo = new RoleVo();
					convertToUserVo(role, roleVo);
					roleVos.add(roleVo);
				}
			}
		}
		return roleVos;
	}
	
	/**
	 * 
	 * @MethodName convertToUserVo
	 * @Description 将角色转换成角色Vo
	 * @author chengui
	 * @date 2013-5-30 下午8:33:46
	 * @param role
	 * @param roleVo
	 */
	private void convertToUserVo(Role role, RoleVo roleVo) {
		BeanUtils.copyProperties(role, roleVo);
	}

	@Override
	public List<RoleVo> getLeftRoleVos(List<RoleVo> roleVos,
			List<RoleVo> ownRoleVos) throws Exception {
		for (RoleVo roleVo : ownRoleVos) {
			roleVos.remove(roleVo);
		}
		return roleVos;
	}
	
	@Transactional
	@Override
	public void allocateRole(UserVo userVo) throws Exception {
		User user = userDao.getById(userVo.getId());
		List<Role> lRoles = roleService.getRoles(userVo);
		Set<Role> sRoles = new HashSet<Role>();
		sRoles.addAll(lRoles);
		user.setRoles(sRoles);
		userDao.update(user);
	}

	@Override
	public UserVo getUserVoByLoginName(String loginName) throws Exception {
		User user = userDao.findUniqueBy("userName", loginName);
		UserVo uv = null;
		if (null != user) {
			uv = new UserVo();
			convertToUserVo(user, uv);
		}
		return uv;
	}

	
	@Override
	public User getUserById(String id) {
		return userDao.findUniqueBy("id", id);
	}

}
